/*
============================================================================
 Name        : LastFmUI.cpp
 Author      : 
 Version     :
 Copyright   : Your copyright notice
 Description : CLastFmUI implementation
============================================================================
*/

#include "LastFmUI.h"
#include "LastFmPlugin.h"
#include "LastFm.mbg"
#include "PluginUtility.h"
#include "Ticker.h"

#include <eikenv.h>				//CEikonEnv

//Bitmap indexes
#define BITMAP_PLAY (TInt)EMbmLastfmPlay
#define BITMAP_PLAY_MASK (TInt)EMbmLastfmPlay_mask
#define BITMAP_BUFFERING (TInt)EMbmLastfmBuffering
#define BITMAP_BUFFERING_MASK (TInt)EMbmLastfmBuffering_mask
#define BITMAP_STOP (TInt)EMbmLastfmStop
#define BITMAP_STOP_MASK (TInt)EMbmLastfmStop_mask
#define BITMAP_ERROR (TInt)EMbmLastfmError
#define BITMAP_ERROR_MASK (TInt)EMbmLastfmError_mask

//Mbm filename
_LIT(KLastFmMbmFileName, "lastfm.mbm");

CLastFmUI::CLastFmUI()
: iContainer(NULL), iTitle(NULL), iImageHandler(NULL), iIsBuffering(EFalse), iPercent(-1), iImageIsReady(EImagePending),
iFontHeight(CEikonEnv::Static()->NormalFont()->HeightInPixels()), iTextWidth(0),
iImage(NULL), iOnFinishCallback(NULL)
{
}

CLastFmUI::~CLastFmUI()
{
	//Delete objects
	DELETE(iTitle);
	DELETE(iImageHandler);
	DELETE(iImage);

	//Delete bitmaps
	iBitmaps.ResetAndDestroy();
}

CLastFmUI* CLastFmUI::NewLC()
{
	CLastFmUI* self = new (ELeave)CLastFmUI();
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
}

CLastFmUI* CLastFmUI::NewL()
{
	CLastFmUI* self = CLastFmUI::NewLC();
	CleanupStack::Pop(); // self;
	return self;
}

void CLastFmUI::ConstructL()
{
	//Load bitmaps
	iBitmaps.Append(CPluginUtility::CreateBitmapL(KLastFmMbmFileName, BITMAP_PLAY));
	iBitmaps.Append(CPluginUtility::CreateBitmapL(KLastFmMbmFileName, BITMAP_PLAY_MASK));
	iBitmaps.Append(CPluginUtility::CreateBitmapL(KLastFmMbmFileName, BITMAP_BUFFERING));
	iBitmaps.Append(CPluginUtility::CreateBitmapL(KLastFmMbmFileName, BITMAP_BUFFERING_MASK));
	iBitmaps.Append(CPluginUtility::CreateBitmapL(KLastFmMbmFileName, BITMAP_STOP));
	iBitmaps.Append(CPluginUtility::CreateBitmapL(KLastFmMbmFileName, BITMAP_STOP_MASK));
	iBitmaps.Append(CPluginUtility::CreateBitmapL(KLastFmMbmFileName, BITMAP_ERROR));
	iBitmaps.Append(CPluginUtility::CreateBitmapL(KLastFmMbmFileName, BITMAP_ERROR_MASK));
}

void CLastFmUI::ImageIsReady(TInt aError)
{
	if (aError)
	{
		iImageIsReady = EImageFailed;
	}
	else
	{
		iImageIsReady = EImageReady;

		//Set bitmap size
		iImageSize = iImage->SizeInPixels();
	}

	//Request completed
	iOnFinishCallback->CallBack();
}

void CLastFmUI::SetContainer(MPluginContainer* aContainer) 
{ 
	iContainer = aContainer; 

	//Recreate ticker
	DELETE(iTitle);
	iTitle = CTicker::NewL(iContainer);
}

void CLastFmUI::SetTitle(const TDesC& aTitle)
{
	iTitle->SetText(aTitle, iTextWidth);
}

void CLastFmUI::SetImageUrl(const TDesC& aImageUrl, TCallBack& aOnFinishCallback)
{
	//Set callback
	iOnFinishCallback = &aOnFinishCallback;

	//Reset bitmap
	iImageIsReady = EImagePending;
	DELETE(iImage);
	iImage = new (ELeave)CFbsBitmap;

	//Convert and resize image
	DELETE(iImageHandler);
	iImageHandler = CImageHandler::NewL(*iImage, *this);
	iImageHandler->GetAndConvertL(aImageUrl, iImageMaxSize);
}

void CLastFmUI::Draw(CWindowGc& aGc, const TRect& aRect) const
{
	//Calculate text width
	TInt* piTextWidth;
	piTextWidth = CONST_CAST(TInt*, &iTextWidth);
	*piTextWidth = aRect.iBr.iX - aRect.iTl.iY - 12;

	//Calculate max size for image
	if (!iImageMaxSize.iWidth && !iImageMaxSize.iHeight)
	{
		TSize* piImageMaxSize;
		piImageMaxSize = CONST_CAST(TSize*, &iImageMaxSize);
		*piImageMaxSize = aRect.Size() - TPoint(4, 4); 
	}

	//Draw image
	if (iImageIsReady == EImageReady)
	{
		TPoint p = aRect.iTl + TPoint((aRect.Width() - iImageSize.iWidth) >> 1, (aRect.Height() - iImageSize.iHeight) >> 1);

		//Draw shadow
		aGc.SetPenColor(BackShadowColor());
		aGc.DrawRect(TRect(p, p + iImageSize + TPoint(2, 2)));

		//Draw border
		aGc.SetPenColor(BackBorderColor());
		aGc.DrawRect(TRect(p + TPoint(-1, -1), p + iImageSize + TPoint(1, 1)));

		//Draw image
		aGc.BitBlt(p, iImage);
	}

	//Draw title
	if (iTitle)
	{
		aGc.SetPenColor(KRgbWhite);
		aGc.DrawText(iTitle->GetText(), TPoint(aRect.iTl.iX + 1, aRect.iTl.iY + iFontHeight + 3));
		
		aGc.SetPenColor(ForeColor());
		aGc.DrawText(iTitle->GetText(), TPoint(aRect.iTl.iX, aRect.iTl.iY + iFontHeight + 2));
	}

	//Draw is buffering
	aGc.SetPenColor(ForeColor());
	if (iIsBuffering)
	{
		TBuf<22> buf;
		buf.AppendFormat(_L("Buffering %d%% ..."), iPercent);
		aGc.DrawText(buf, TPoint(aRect.iTl.iX, aRect.iBr.iY - 4));
	}
}

void CLastFmUI::SetTickerIcon(TLastFmTickerIcon aIcon)
{
	TInt index = -1, indexMask;

	switch (aIcon)
	{
	case EPlay:
		index = BITMAP_PLAY;
		indexMask = BITMAP_PLAY_MASK;
		break;

	case EBuffering:
		index = BITMAP_BUFFERING;
		indexMask = BITMAP_BUFFERING_MASK;
		break;

	case EStop:
		index = BITMAP_STOP;
		indexMask = BITMAP_STOP_MASK;
		break;

	case EError:
		index = BITMAP_ERROR;
		indexMask = BITMAP_ERROR_MASK;
		break;

	default:
		break;
	}
	if (index < 0) 
	{
		iContainer->SetTickerIcon(NULL, NULL);
	}
	else
	{
		iContainer->SetTickerIcon(iBitmaps[index], iBitmaps[indexMask]);
	}
}

void CLastFmUI::SetTickerText(const TDesC& aText)
{
	iMetadata.Copy(aText);
	iContainer->SetTickerText(iMetadata);
}

void CLastFmUI::SetTickerTextFormat(TRefByValue<const TDesC16> aFmt, ...)
{
	iMetadata.Zero();
	iMetadata.AppendFormat(aFmt);
	iContainer->SetTickerText(iMetadata);
}

void CLastFmUI::SetIsBuffering(TBool aIsBuffering, TInt aPercent) 
{ 
	if (aIsBuffering == iIsBuffering && aPercent == iPercent) return;
	
	//Save state and percent
	iIsBuffering = aIsBuffering;
	iPercent = aPercent;

	//Icon
	SetTickerIcon(iIsBuffering ? EBuffering : EPlay);

	//Repaint
	iContainer->Repaint();
}

void CLastFmUI::Activate()
{
	//Set container ticker
	SetTickerIcon(iMetadata.Length() > 0 ? EStop : ENull);
	iContainer->SetTickerText(iMetadata);

	//Activate ticker
	iTitle->Activate();
}

void CLastFmUI::Deactivate()
{
	//Deactivate ticker
	iTitle->Deactivate();
}
